package nckd.wnqjt.tmc.tda.plugin.form;

import kd.bos.algo.DataSet;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.FilterItemInfo;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 借款表
 * xiao
 * nckd_loandetails
 * 查询插件
 */

public class LoanDetailsQueryPlugin extends AbstractReportListDataPlugin {

    //提款中,已提款,已部分还款
    private final String[] drawTypes = {"drawed", "partpayment"};

    @Override
    public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {

        List<QFilter> filters = new ArrayList<>();
        //获取过滤条件
        List<FilterItemInfo> filterItems = reportQueryParam.getFilter().getFilterItems();
        filterItems.forEach(item -> {
            if ("nckd_orgf".equals(item.getPropName()) && item.getValue() != null) {
                Object value = item.getValue();
                DynamicObjectCollection nckdOrg = null;
                if (value != null) {
                    nckdOrg = (DynamicObjectCollection) value;
                    List<Long> longList = nckdOrg.stream().map(e -> e.getLong("id")).collect(Collectors.toList());
                    QFilter orgFilter = new QFilter("org.id", QCP.in, longList);
                    filters.add(orgFilter);
                }
            }
        });
        //单据状态=已审核
        filters.add(new QFilter("billstatus", QCP.equals, "C"));
        //确认状态=已确认
        filters.add(new QFilter("confirmstatus", QCP.equals, "yetconfirm"));
        //债权人类型=银行
        QFilter bankFilter = new QFilter("creditortype", QCP.equals, "bank");
        filters.add(bankFilter);
        //提款业务状态=提款中,已提款,已部分还款
        filters.add(new QFilter("drawtype", QCP.in, drawTypes));

        List<Object> longDebtIds = new ArrayList<>();
        List<Object> middleDebtIds = new ArrayList<>();
        //借款期限小于等于1年的提款单余额
        List<Object> shortDebtIds = new ArrayList<>();

        //查询提款处理
        DynamicObject[] cfm = BusinessDataServiceHelper.load("cfm_loanbill", "id,org,billstatus,confirmstatus,creditortype,bizdate,expiredate,renewalexpiredate"
                , filters.toArray(new QFilter[filters.size()]));
        if (cfm.length != 0) {
            Arrays.asList(cfm).forEach(item -> {
                Date strDate = item.getDate("bizdate");
                Date endDate = item.getDate("expiredate");
                long index = DateUtils.getDateResult(strDate, endDate);
                long middleIndex = DateUtils.getDateResult(DateUtils.getNowMonthToDate(), endDate);

                if (index <= 0) {
                    shortDebtIds.add(item.getPkValue());
                } else if (index > 0 && middleIndex <= 0) {
                    middleDebtIds.add(item.getPkValue());
                } else if (index > 0 && middleIndex > 0) {
                    longDebtIds.add(item.getPkValue());
                }
            });
        }


        /**
         * 查询长期借款数据
         */
        QFilter longDebtFilter = new QFilter("id", QCP.in, longDebtIds);
        filters.add(longDebtFilter);
        //Tyx 2025-04-02 取合同最新利率
        String longDebtFiled = "id,billstatus,confirmstatus,creditortype,org,org.id,org.name as nckd_org,textcreditor as nckd_bank,loancontractbill.interestrate as nckd_rate,bizdate as nckd_loandate,expiredate,renewalexpiredate,loancontractbill.number as nckd_contractnumber,notrepayamount as nckd_longloan,notrepayamount as nckd_total,drawtype";
        DataSet longDebtData = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cfm_loanbill", longDebtFiled, filters.toArray(new QFilter[filters.size()]), null);
        longDebtData = longDebtData.select("id", "nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "case when renewalexpiredate is null then expiredate else renewalexpiredate end as nckd_repaydate", "nckd_contractnumber", "0 as nckd_shortloan", "0 as nckd_yearlongloan", "nckd_longloan", "0 as nckd_interiorloan", "0 as nckd_bond", "nckd_total");

        /**
         * 查询一年内到期长期借款数据
         */
        QFilter middleDebtFilter = new QFilter("id", QCP.in, middleDebtIds);
        filters.set(filters.indexOf(longDebtFilter), middleDebtFilter);
        //Tyx 2025-04-02 取合同最新利率
        String middleDebtFiled = "id,billstatus,confirmstatus,creditortype,org,org.id,org.name as nckd_org,textcreditor as nckd_bank,loancontractbill.interestrate as nckd_rate,bizdate as nckd_loandate,expiredate,renewalexpiredate,loancontractbill.number as nckd_contractnumber,notrepayamount as nckd_yearlongloan,notrepayamount as nckd_total,drawtype";
        DataSet middleDebtData = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cfm_loanbill", middleDebtFiled, filters.toArray(new QFilter[filters.size()]), null);
        middleDebtData = middleDebtData.select("id", "nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "case when renewalexpiredate is null then expiredate else renewalexpiredate end as nckd_repaydate", "nckd_contractnumber", "0 as nckd_shortloan", "nckd_yearlongloan", "0 as nckd_longloan", "0 as nckd_interiorloan", "0 as nckd_bond", "nckd_total");

        /**
         * 查询短期借款数据
         */
        QFilter shortDebtFilter = new QFilter("id", QCP.in, shortDebtIds);
        filters.set(filters.indexOf(middleDebtFilter), shortDebtFilter);
        //Tyx 2025-04-02 取合同最新利率
        String shortDebtFiled = "id,billstatus,confirmstatus,creditortype,org,org.id,org.name as nckd_org,textcreditor as nckd_bank,loancontractbill.interestrate as nckd_rate,bizdate as nckd_loandate,expiredate,renewalexpiredate,loancontractbill.number as nckd_contractnumber,notrepayamount as nckd_shortloan,notrepayamount as nckd_total,drawtype";
        DataSet shortDebtData = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cfm_loanbill", shortDebtFiled, filters.toArray(new QFilter[filters.size()]), null);
        shortDebtData = shortDebtData.select("id", "nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "case when renewalexpiredate is null then expiredate else renewalexpiredate end as nckd_repaydate", "nckd_contractnumber", "nckd_shortloan", "0 as nckd_yearlongloan", "0 as nckd_longloan", "0 as nckd_interiorloan", "0 as nckd_bond", "nckd_total");

        /**
         * 查询内部交易数据
         */
        QFilter interiorFilter = new QFilter("creditortype", QCP.not_equals, "bank").and(new QFilter("creditortype", QCP.not_equals, "finorg"));
        filters.set(filters.indexOf(bankFilter), interiorFilter);
        filters.remove(filters.size() - 1);
        //Tyx 2025-04-02 取合同最新利率
        String interiorFiled = "id,billstatus,confirmstatus,creditortype,org,org.id,org.name as nckd_org,textcreditor as nckd_bank,loancontractbill.interestrate as nckd_rate,bizdate as nckd_loandate,expiredate,renewalexpiredate,loancontractbill.number as nckd_contractnumber,notrepayamount as nckd_interiorloan,notrepayamount as nckd_total,drawtype";
        DataSet interiorData = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cfm_loanbill", interiorFiled, filters.toArray(new QFilter[filters.size()]), null);
        interiorData = interiorData.select("id", "nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "case when renewalexpiredate is null then expiredate else renewalexpiredate end as nckd_repaydate", "nckd_contractnumber", "0 as nckd_shortloan", "0 as nckd_yearlongloan", "0 as nckd_longloan", "nckd_interiorloan", "0 as nckd_bond", "nckd_total");

        /**
         * 查询债券类数据
         */
        QFilter bondFilter = new QFilter("creditortype", QCP.equals, "finorg");
        filters.set(filters.indexOf(interiorFilter), bondFilter);
        //Tyx 2025-04-02 取合同最新利率
        String bondFiled = "id,billstatus,confirmstatus,creditortype,org,org.id,org.name as nckd_org,textcreditor as nckd_bank,loancontractbill.interestrate as nckd_rate,bizdate as nckd_loandate,expiredate,renewalexpiredate,loancontractbill.number as nckd_contractnumber,notrepayamount as nckd_bond,notrepayamount as nckd_total,drawtype";
        DataSet bondData = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cfm_loanbill", bondFiled, filters.toArray(new QFilter[filters.size()]), null);
        bondData = bondData.select("id", "nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "case when renewalexpiredate is null then expiredate else renewalexpiredate end as nckd_repaydate", "nckd_contractnumber", "0 as nckd_shortloan", "0 as nckd_yearlongloan", "0 as nckd_longloan", "0 as nckd_interiorloan", "nckd_bond", "nckd_total");


        DataSet resultDataSet = longDebtData.union(middleDebtData).union(shortDebtData).union(interiorData).union(bondData);
        resultDataSet = resultDataSet.select("id", "nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "nckd_repaydate", "nckd_contractnumber", "(nckd_shortloan/10000) as nckd_shortloan", "(nckd_yearlongloan/10000) as nckd_yearlongloan", "(nckd_longloan/10000) as nckd_longloan", "(nckd_interiorloan/10000) as nckd_interiorloan", "nckd_bond", "1 as count", "case when nckd_repaydate < Date() then '2' else '1' end as nckd_count", "(nckd_total/10000) as nckd_total", "1 as nckd_countTotal");

        Map<String, Object> customParam = reportQueryParam.getCustomParam();
        List<String> list = (ArrayList<String>) customParam.get("id");
        if (list != null) {
            List<Long> longList = list.stream().map(e -> Long.valueOf(e)).collect(Collectors.toList());
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < longList.size(); i++) {
                Long id = longList.get(i);
                if (longList.size() - 1 == i) {
                    sb.append(id);
                } else {
                    sb.append(id).append(",");
                }
            }
            resultDataSet = resultDataSet.filter("id in (" + sb + ")");
        }

        //增加组织汇总行
        DataSet groupDataSet = resultDataSet.groupBy(new String[]{"nckd_org"}).sum("nckd_shortloan").sum("nckd_yearlongloan").sum("nckd_longloan").sum("nckd_interiorloan").sum("nckd_bond").sum("nckd_total").finish();
        groupDataSet = groupDataSet.select(new String[]{"null as id", "nckd_org", "concat('合计') as nckd_bank", "nckd_shortloan", "nckd_yearlongloan", "nckd_longloan", "nckd_interiorloan", "nckd_bond", "2 as count", "'1' as nckd_count", "nckd_total"});//"'-' as nckd_bank","'-' as nckd_rate","'-' as nckd_loandate","'-' as nckd_repaydate","'-' as nckd_contractnumber",
        groupDataSet = groupDataSet.addField("0", "nckd_rate").addField("null", "nckd_loandate").addField("null", "nckd_repaydate").addField("'-'", "nckd_contractnumber");
        groupDataSet = groupDataSet.select("id", "nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "nckd_repaydate", "nckd_contractnumber", "nckd_shortloan", "nckd_yearlongloan", "nckd_longloan", "nckd_interiorloan", "nckd_bond", "count", "nckd_count", "nckd_total", "1 as nckd_countTotal");

        //增加汇总行
        DataSet total = resultDataSet.select("id", "'-' as nckd_org", "concat('集团总计') as nckd_bank", "0 as nckd_rate", "null as nckd_loandate", "null as nckd_repaydate", "'-' as nckd_contractnumber", "nckd_shortloan", "nckd_yearlongloan", "nckd_longloan", "nckd_interiorloan", "nckd_bond", "3 as count", "nckd_total");
        total = total.groupBy(new String[]{"nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "nckd_repaydate", "nckd_contractnumber", "count"}).sum("nckd_shortloan").sum("nckd_yearlongloan").sum("nckd_longloan").sum("nckd_interiorloan").sum("nckd_bond").sum("nckd_total").finish();
        total = total.select("null as id", "nckd_org", "nckd_bank", "nckd_rate", "nckd_loandate", "nckd_repaydate", "nckd_contractnumber", "nckd_shortloan", "nckd_yearlongloan", "nckd_longloan", "nckd_interiorloan", "nckd_bond", "count", "'1' as nckd_count", "nckd_total", "2 as nckd_countTotal");
        DataSet unionDataSet = resultDataSet.union(groupDataSet).union(total);

        DataSet dataSet = unionDataSet.orderBy(new String[]{"nckd_org", "count"}).orderBy(new String[]{"nckd_countTotal"});

        return dataSet;
    }
}
